package com.gitee.wsl.platform.network

import com.gitee.wsl.platform.platformPrintErr
import kotlinx.coroutines.CancellationException

/** IP resolver contract */
interface IpResolver {
    suspend fun get(): String?
}

/** The connection info */
data class ConnectionInfo(
    val ipv4: String? = null,
    val ipv6: String? = null,
    val externalIp: String? = null
)

/** Returns the ip info from the current Network Connection. */
expect suspend fun NetworkChecker.getInfo(): ConnectionInfo?

suspend fun NetworkChecker.getInfo(vararg ipResolver: IpResolver): ConnectionInfo?{
    val info = getInfo()?:return null
    return info.copy(
        externalIp = ipResolver.firstNotNullOfOrNull {
            it.get()
        }
    )
}

abstract class BaseIpResolverImpl(
    private val enableDebugLog: Boolean,
    private val tag: String,
    private val serviceUrl: String,
    private val getUrlContent: (url: String) -> String?
): IpResolver {
    @Suppress("TooGenericExceptionCaught")
    override suspend fun get(): String? =
        try {
            getUrlContent(serviceUrl)
        } catch (error: CancellationException) {
            throw error
        } catch (error: Throwable) {
            if (enableDebugLog) {
                platformPrintErr(tag+"error on get()"+error)
            }
            null
        }
}

class MyExternalIpResolver(enableDebugLog: Boolean,getUrlContent: (url: String) -> String?) : BaseIpResolverImpl(
    enableDebugLog = enableDebugLog,
    tag = "MyExternalIpResolver",
    serviceUrl = "https://myexternalip.com/raw",
    getUrlContent = getUrlContent
)

class IPv6TestIpResolver(enableDebugLog: Boolean,getUrlContent: (url: String) -> String?) : BaseIpResolverImpl(
    enableDebugLog = enableDebugLog,
    tag = "IPv6TestIpResolver",
    serviceUrl = "https://v4v6.ipv6-test.com/api/myip.php",
    getUrlContent = getUrlContent
)